﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Svg;
using System.Drawing;
using System.Runtime.Serialization;
using Commons;
using Svg.Pathing;
using Svg.Transforms;

namespace HumanFace
{
    [DataContract]
    public class Lips : Entities.Base.LipsBASE
    {
        public Lips(NodeCollection pointList, Dictionary<string, string> templates)
            : base(templates,pointList)
        {
            CreateProperties();
            RenderVectorelGraphic();

        }
        public Lips()
        {
        }
        private void CreateProperties()
        {
            #region Height
            Node nd48 = PointList["48"];
            Node nd54 = PointList["54"];
            Node nd61 = PointList["61"];
            if (nd48 != null && nd54 != null && nd61 != null)
            {
                float top = (nd48.Y < nd54.Y) ? nd48.Y : nd54.Y;
                this.Height = nd61.Y - top;
            }
            #endregion
            #region Width
            if (nd48 != null && nd54 != null)
                this.Width = nd54.X - nd48.X;
            #endregion
        }
        protected override void RenderVectorelGraphic()
        {
            base.RenderVectorelGraphic();
            if (this.SVG != null)
            {
                this.SVG.ID = "lips";
                SvgPath lipsCurve = this.SVG.GetElementById<SvgPath>("lipsCurve");
                SvgPath lipsCurveShadow = this.SVG.GetElementById<SvgPath>("lipsCurveShadow");
                float templateWidth = ((SvgCubicCurveSegment)lipsCurve.PathData[6]).End.X;
                float templateHeight = ((SvgCubicCurveSegment)lipsCurveShadow.PathData[3]).End.Y;
                float ratioX = templateWidth / this.Width;
                float ratioY = templateHeight / this.Height;

                SetLipsCurve(lipsCurve, ratioX, ratioY);
                SetLipsCurveShadow(lipsCurveShadow, ratioX, ratioY);

                SvgTransformCollection transformCollection = new SvgTransformCollection();
                SvgGroup lipsGroup = this.SVG.GetElementById<SvgGroup>("lipsGroup");
                if (lipsGroup.Transforms != null) transformCollection = lipsGroup.Transforms;
                SketchHelper.Scale(1 / ratioX, 1 / ratioY, transformCollection);
                lipsGroup.Transforms = transformCollection;
            }
        }
        private void SetLipsCurve(SvgPath lipsCurve,float ratioX, float ratioY)
        {
            #region lpathDataProps
            SvgMoveToSegment pathData0 = ((SvgMoveToSegment)lipsCurve.PathData[0]);
            SvgCubicCurveSegment pathData1 = ((SvgCubicCurveSegment)lipsCurve.PathData[1]);
            SvgCubicCurveSegment pathData2 = ((SvgCubicCurveSegment)lipsCurve.PathData[2]);
            SvgCubicCurveSegment pathData3 = ((SvgCubicCurveSegment)lipsCurve.PathData[3]);
            SvgCubicCurveSegment pathData4 = ((SvgCubicCurveSegment)lipsCurve.PathData[4]);
            SvgCubicCurveSegment pathData5 = ((SvgCubicCurveSegment)lipsCurve.PathData[5]);
            SvgCubicCurveSegment pathData6 = ((SvgCubicCurveSegment)lipsCurve.PathData[6]);
            SvgCubicCurveSegment pathData7 = ((SvgCubicCurveSegment)lipsCurve.PathData[7]);
            SvgCubicCurveSegment pathData8 = ((SvgCubicCurveSegment)lipsCurve.PathData[8]);
            SvgCubicCurveSegment pathData9 = ((SvgCubicCurveSegment)lipsCurve.PathData[9]);
            SvgCubicCurveSegment pathData10 = ((SvgCubicCurveSegment)lipsCurve.PathData[10]);
            #endregion

            #region borderProps
            float border09 = pathData0.End.Y - pathData9.End.Y;
            float border18 = pathData1.End.Y - pathData8.End.Y;
            float border27 = pathData2.End.Y - pathData7.End.Y;
            float border36 = pathData3.End.Y - pathData6.End.Y;
            float border45 = pathData4.End.Y - pathData5.End.Y;
            #endregion
            PointF[] plist = new PointF[11];
            plist[0] = new PointF((this.PointList["48"].X - this.MostLeftPoint.X) * ratioX, (this.PointList["48"].Y - this.MostTopPoint.Y) * ratioY + border09);
            plist[1] = new PointF((this.PointList["60"].X - this.MostLeftPoint.X) * ratioX, (this.PointList["60"].Y - this.MostTopPoint.Y) * ratioY + border18);
            plist[2] = new PointF((this.PointList["61"].X - this.MostLeftPoint.X) * ratioX, (this.PointList["61"].Y - this.MostTopPoint.Y) * ratioY + border27);
            plist[3] = new PointF((this.PointList["62"].X - this.MostLeftPoint.X) * ratioX, (this.PointList["62"].Y - this.MostTopPoint.Y) * ratioY + border36);
            plist[4] = new PointF((this.PointList["54"].X - this.MostLeftPoint.X) * ratioX, (this.PointList["54"].Y - this.MostTopPoint.Y) * ratioY + border45);
            plist[5] = new PointF((this.PointList["54"].X - this.MostLeftPoint.X) * ratioX, (this.PointList["54"].Y - this.MostTopPoint.Y) * ratioY);
            plist[6] = new PointF((this.PointList["62"].X - this.MostLeftPoint.X) * ratioX, (this.PointList["62"].Y - this.MostTopPoint.Y) * ratioY);
            plist[7] = new PointF((this.PointList["61"].X - this.MostLeftPoint.X) * ratioX, (this.PointList["61"].Y - this.MostTopPoint.Y) * ratioY);
            plist[8] = new PointF((this.PointList["60"].X - this.MostLeftPoint.X) * ratioX, (this.PointList["60"].Y - this.MostTopPoint.Y) * ratioY);
            plist[9] = new PointF((this.PointList["48"].X - this.MostLeftPoint.X) * ratioX, (this.PointList["48"].Y - this.MostTopPoint.Y) * ratioY);
            plist[10] = plist[0];
            #region pathData1
            float pathData1curveDifferenceX = plist[1].X - pathData1.End.X;
            float pathData1curveDifferenceY = plist[1].Y - pathData1.End.Y;
            //rpathData1.FirstControlPoint = new PointF(rpathData1.FirstControlPoint.X + rpathData0curveDifferenceX, rpathData1.FirstControlPoint.Y + rpathData0curveDifferenceY);
            pathData1.SecondControlPoint = new PointF(pathData1.SecondControlPoint.X + pathData1curveDifferenceX, pathData1.SecondControlPoint.Y + pathData1curveDifferenceY);
            pathData1.End = plist[1];
            //rpathData1.Start = rpathData0.End;
            #endregion
            #region pathData2
            float pathData2curveDifferenceX = plist[2].X - pathData2.End.X;
            float pathData2curveDifferenceY = plist[2].Y - pathData2.End.Y;
            pathData2.FirstControlPoint = new PointF(pathData2.FirstControlPoint.X + pathData1curveDifferenceX, pathData2.FirstControlPoint.Y + pathData1curveDifferenceY);
            pathData2.SecondControlPoint = new PointF(pathData2.SecondControlPoint.X + pathData2curveDifferenceX, pathData2.SecondControlPoint.Y + pathData2curveDifferenceY);
            pathData2.End = plist[2];
            pathData2.Start = pathData1.End;
            #endregion
            ////float differenceY34 = rpathData4.End.Y - rpathData3.End.Y;
            #region pathData3
            float pathData3curveDifferenceX = plist[3].X - pathData3.End.X;
            float pathData3curveDifferenceY = plist[3].Y - pathData3.End.Y;
            pathData3.FirstControlPoint = new PointF(pathData3.FirstControlPoint.X + pathData2curveDifferenceX, pathData3.FirstControlPoint.Y + pathData2curveDifferenceY);
            pathData3.SecondControlPoint = new PointF(pathData3.SecondControlPoint.X + pathData3curveDifferenceX, pathData3.SecondControlPoint.Y + pathData3curveDifferenceY);
            pathData3.End = plist[3];
            pathData3.Start = pathData2.End;
            #endregion
            #region pathData4
            float pathData4curveDifferenceX = plist[4].X - pathData4.End.X;
            float pathData4curveDifferenceY = plist[4].Y - pathData4.End.Y;
            pathData4.FirstControlPoint = new PointF(pathData4.FirstControlPoint.X + pathData3curveDifferenceX, pathData4.FirstControlPoint.Y + pathData3curveDifferenceY);
            pathData4.SecondControlPoint = new PointF(pathData4.SecondControlPoint.X + pathData4curveDifferenceX, pathData4.SecondControlPoint.Y + pathData4curveDifferenceY);
            pathData4.End = plist[4];
            pathData4.Start = pathData3.End;
            #endregion
            #region pathData5
            float pathData5curveDifferenceX = plist[5].X - pathData5.End.X;
            float pathData5curveDifferenceY = plist[5].Y - pathData5.End.Y;
            pathData5.FirstControlPoint = new PointF(pathData5.FirstControlPoint.X + pathData4curveDifferenceX, pathData5.FirstControlPoint.Y + pathData4curveDifferenceY);
            pathData5.SecondControlPoint = new PointF(pathData5.SecondControlPoint.X + pathData5curveDifferenceX, pathData5.SecondControlPoint.Y + pathData5curveDifferenceY);
            pathData5.End = plist[5];
            pathData5.Start = pathData4.End;
            #endregion
            #region pathData6
            float pathData6curveDifferenceX = plist[6].X - pathData6.End.X;
            float pathData6curveDifferenceY = plist[6].Y - pathData6.End.Y;
            pathData6.FirstControlPoint = new PointF(pathData6.FirstControlPoint.X + pathData5curveDifferenceX, pathData6.FirstControlPoint.Y + pathData5curveDifferenceY);
            pathData6.SecondControlPoint = new PointF(pathData6.SecondControlPoint.X + pathData6curveDifferenceX, pathData6.SecondControlPoint.Y + pathData6curveDifferenceY);
            pathData6.End = plist[6];
            pathData6.Start = pathData5.End;
            #endregion
            #region pathData7
            float pathData7curveDifferenceX = plist[7].X - pathData7.End.X;
            float pathData7curveDifferenceY = plist[7].Y - pathData7.End.Y;
            pathData7.FirstControlPoint = new PointF(pathData7.FirstControlPoint.X + pathData6curveDifferenceX, pathData7.FirstControlPoint.Y + pathData6curveDifferenceY);
            pathData7.SecondControlPoint = new PointF(pathData7.SecondControlPoint.X + pathData7curveDifferenceX, pathData7.SecondControlPoint.Y + pathData7curveDifferenceY);
            pathData7.End = plist[7];
            pathData7.Start = pathData6.End;
            #endregion
            #region pathData8
            float pathData8curveDifferenceX = plist[8].X - pathData8.End.X;
            float pathData8curveDifferenceY = plist[8].Y - pathData8.End.Y;
            pathData8.FirstControlPoint = new PointF(pathData8.FirstControlPoint.X + pathData7curveDifferenceX, pathData8.FirstControlPoint.Y + pathData7curveDifferenceY);
            pathData8.SecondControlPoint = new PointF(pathData8.SecondControlPoint.X + pathData8curveDifferenceX, pathData8.SecondControlPoint.Y + pathData8curveDifferenceY);
            pathData8.End = plist[8];
            pathData8.Start = pathData7.End;
            #endregion
            #region pathData9
            float pathData9curveDifferenceX = plist[9].X - pathData9.End.X;
            float pathData9curveDifferenceY = plist[9].Y - pathData9.End.Y;
            pathData9.FirstControlPoint = new PointF(pathData9.FirstControlPoint.X + pathData8curveDifferenceX, pathData9.FirstControlPoint.Y + pathData8curveDifferenceY);
            pathData9.SecondControlPoint = new PointF(pathData9.SecondControlPoint.X + pathData9curveDifferenceX, pathData9.SecondControlPoint.Y + pathData9curveDifferenceY);
            pathData9.End = plist[9];
            pathData9.Start = pathData8.End;
            #endregion
            #region pathData10
            float pathData10curveDifferenceX = plist[10].X - pathData10.End.X;
            float pathData10curveDifferenceY = plist[10].Y - pathData10.End.Y;
            pathData10.FirstControlPoint = new PointF(pathData10.FirstControlPoint.X + pathData9curveDifferenceX, pathData10.FirstControlPoint.Y + pathData9curveDifferenceY);
            pathData10.SecondControlPoint = new PointF(pathData10.SecondControlPoint.X + pathData10curveDifferenceX, pathData10.SecondControlPoint.Y + pathData10curveDifferenceY);
            pathData10.End = plist[10];
            pathData10.Start = pathData9.End;
            #endregion
            pathData0.Start = pathData10.End;
            pathData0.End = pathData10.End;
            pathData1.Start = pathData0.End;
            pathData1.FirstControlPoint = new PointF(pathData1.FirstControlPoint.X + pathData10curveDifferenceX, pathData1.FirstControlPoint.Y + pathData10curveDifferenceY);
        }
        private void SetLipsCurveShadow(SvgPath lipsCurveShadow,float ratioX, float ratioY)
        {

            #region lpathDataProps
            SvgMoveToSegment pathData0 = ((SvgMoveToSegment)lipsCurveShadow.PathData[0]);
            SvgCubicCurveSegment pathData1 = ((SvgCubicCurveSegment)lipsCurveShadow.PathData[1]);
            SvgCubicCurveSegment pathData2 = ((SvgCubicCurveSegment)lipsCurveShadow.PathData[2]);
            SvgCubicCurveSegment pathData3 = ((SvgCubicCurveSegment)lipsCurveShadow.PathData[3]);
            SvgCubicCurveSegment pathData4 = ((SvgCubicCurveSegment)lipsCurveShadow.PathData[4]);
            #endregion

            #region borderProps
            float border13 = pathData1.End.Y - pathData3.End.Y;
            #endregion
            PointF[] plist = new PointF[5];
            plist[0] = new PointF((this.PointList["48"].X - this.MostLeftPoint.X) * ratioX, (this.PointList["48"].Y - this.MostTopPoint.Y) * ratioY);
            plist[1] = new PointF((this.PointList["61"].X - this.MostLeftPoint.X) * ratioX, (this.PointList["61"].Y - this.MostTopPoint.Y) * ratioY + border13);
            plist[2] = new PointF((this.PointList["54"].X - this.MostLeftPoint.X) * ratioX, (this.PointList["54"].Y - this.MostTopPoint.Y) * ratioY);
            plist[3] = new PointF((this.PointList["61"].X - this.MostLeftPoint.X) * ratioX, (this.PointList["61"].Y - this.MostTopPoint.Y) * ratioY);
            plist[4] = plist[0];
            #region pathData1
            float pathData1curveDifferenceX = plist[1].X - pathData1.End.X;
            float pathData1curveDifferenceY = plist[1].Y - pathData1.End.Y;
            //rpathData1.FirstControlPoint = new PointF(rpathData1.FirstControlPoint.X + rpathData0curveDifferenceX, rpathData1.FirstControlPoint.Y + rpathData0curveDifferenceY);
            pathData1.SecondControlPoint = new PointF(pathData1.SecondControlPoint.X + pathData1curveDifferenceX, pathData1.SecondControlPoint.Y + pathData1curveDifferenceY);
            pathData1.End = plist[1];
            //rpathData1.Start = rpathData0.End;
            #endregion
            #region pathData2
            float pathData2curveDifferenceX = plist[2].X - pathData2.End.X;
            float pathData2curveDifferenceY = plist[2].Y - pathData2.End.Y;
            pathData2.FirstControlPoint = new PointF(pathData2.FirstControlPoint.X + pathData1curveDifferenceX, pathData2.FirstControlPoint.Y + pathData1curveDifferenceY);
            pathData2.SecondControlPoint = new PointF(pathData2.SecondControlPoint.X + pathData2curveDifferenceX, pathData2.SecondControlPoint.Y + pathData2curveDifferenceY);
            pathData2.End = plist[2];
            pathData2.Start = pathData1.End;
            #endregion
            #region pathData3
            float pathData3curveDifferenceX = plist[3].X - pathData3.End.X;
            float pathData3curveDifferenceY = plist[3].Y - pathData3.End.Y;
            pathData3.FirstControlPoint = new PointF(pathData3.FirstControlPoint.X + pathData2curveDifferenceX, pathData3.FirstControlPoint.Y + pathData2curveDifferenceY);
            pathData3.SecondControlPoint = new PointF(pathData3.SecondControlPoint.X + pathData3curveDifferenceX, pathData3.SecondControlPoint.Y + pathData3curveDifferenceY);
            pathData3.End = plist[3];
            pathData3.Start = pathData2.End;
            #endregion
            #region pathData4
            float pathData4curveDifferenceX = plist[4].X - pathData4.End.X;
            float pathData4curveDifferenceY = plist[4].Y - pathData4.End.Y;
            pathData4.FirstControlPoint = new PointF(pathData4.FirstControlPoint.X + pathData3curveDifferenceX, pathData4.FirstControlPoint.Y + pathData3curveDifferenceY);
            pathData4.SecondControlPoint = new PointF(pathData4.SecondControlPoint.X + pathData4curveDifferenceX, pathData4.SecondControlPoint.Y + pathData4curveDifferenceY);
            pathData4.End = plist[4];
            pathData4.Start = pathData3.End;
            #endregion
            pathData0.Start = pathData4.End;
            pathData0.End = pathData4.End;
            pathData1.Start = pathData0.End;
            pathData1.FirstControlPoint = new PointF(pathData1.FirstControlPoint.X + pathData4curveDifferenceX, pathData1.FirstControlPoint.Y + pathData4curveDifferenceY);
        
        }
    }
}
